<template>
  <div ref="container" style="height:100vh;"></div>
</template>

<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from 'vue';
import { Terminal } from "xterm";
import { FitAddon } from 'xterm-addon-fit';
import "xterm/css/xterm.css";
import { ConnectData } from '../model/SSHModel'
import { useRoute } from 'vue-router'

const route = useRoute()
const id = route.query.id as string
const name = route.query.name as string
const container = ref<HTMLElement>({} as HTMLElement)
const connectData = ref<ConnectData>({
  operate:'connect',
  cols: 0,
  rows: 0,
  id: id
})

const websockt = ref<WebSocket>({} as WebSocket)
const fitAddon = ref<FitAddon>({} as FitAddon)
const term = ref<Terminal>({} as Terminal)

onMounted(() => {
  document.title = name
  term.value = buildTerminal()
  fitAddon.value = new FitAddon();
  term.value.loadAddon(fitAddon.value);
  term.value.open(container.value);
  fitAddon.value.fit();
  connectData.value.cols = term.value.cols;
  connectData.value.rows = term.value.rows;

  initWebSocket();
  
  window.addEventListener("resize", () => {
    if(websockt.value.readyState == 1){  
      fitAddon.value.fit();
      websocketsend(JSON.stringify({"operate": "resize", "cols": term.value.cols, "rows": term.value.rows}));
    }
  });

  term.value.onData((data) => {
    //键盘输入时的回调函数
    websocketsend(JSON.stringify({"operate": "command", "command": data}));
  });

  term.value.write('Connecting...\r\n');
})

onBeforeUnmount(() => {
  websockt.value.close()
  term.value.dispose()
})

window.onbeforeunload = function () {
  websockt.value.close()
  term.value.dispose()
}

const buildTerminal = () => {
  return new Terminal({
    cursorBlink: true, // 光标闪烁
    cursorStyle: "block", // 光标样式  null | 'block' | 'underline' | 'bar'
    scrollback: 1000, //回滚
    tabStopWidth: 4, //制表宽度
  });
}

const initWebSocket = () => {
  const path = 'ws://' + window.location.host + '/ssh'
  websockt.value = new WebSocket(path);
  websockt.value.onmessage = websocketonmessage;
  websockt.value.onopen = websocketonopen;
  websockt.value.onerror = websocketonerror;
  websockt.value.onclose = websocketclose;
}

const websocketonopen = () => { //连接建立之后执行send方法发送数据
  websocketsend(JSON.stringify(connectData.value));
}

const websocketonerror = (error:Event) => {//连接建立失败重连
  if(!term.value){
    return
  }
  term.value.write('Error: ' + error + '\r\n');
}

const websocketonmessage = (e: MessageEvent) => { //数据接收
  if(e.data.indexOf('logout') != -1){
    term.value.dispose();
    websockt.value.close();
  }else{
    term.value.write(e.data);
  }
}

const websocketsend = (data:string) => {//数据发送
  websockt.value.send(data);
}

const websocketclose = (e:CloseEvent) => {  //关闭
  console.log('断开连接',e);
  term.value.dispose();
}
</script>